"""
Command-line interface for DeepSeek client
"""

import argparse
import sys
import json
from pathlib import Path
from typing import Optional

from .ds_core import DeepSeekClient, DeepSeekConfig
from .utils import setup_logging, load_env_file, validate_api_key
from .history import QAHistoryManager
import re
from concurrent.futures import ThreadPoolExecutor
import time


def create_simple_parser():
    """Create parser for simple interface (like ds-client)"""
    parser = argparse.ArgumentParser(
        description="DeepSeek Client - AI-powered text analysis and question answering"
    )
    
    # Simple interface arguments
    parser.add_argument("prompt", nargs="?", help="Text prompt to ask DeepSeek")
    parser.add_argument("--file", "-f", type=str, help="File containing text to use as prompt")
    
    # History commands
    parser.add_argument("--list", action="store_true", help="List all Q&A history with question IDs")
    parser.add_argument("--show", type=int, metavar="QUESTION_ID", help="Show full Q&A for specific question ID")
    
    # Global options
    parser.add_argument("--config", type=str, help="Path to config file")
    parser.add_argument("--api-key", type=str, help="DeepSeek API key")
    parser.add_argument("--base-url", type=str, help="API base URL")
    parser.add_argument("--model", type=str, help="Model name")
    parser.add_argument("--log-level", type=str, default="INFO", 
                       choices=["DEBUG", "INFO", "WARNING", "ERROR"],
                       help="Logging level")
    parser.add_argument("--log-file", type=str, help="Log file path")
    parser.add_argument("--env-file", type=str, help="Environment file path")
    parser.add_argument("--system-prompt", type=str, help="System prompt for simple mode")
    
    return parser


def create_subcommand_parser():
    """Create parser for advanced subcommand interface"""
    parser = argparse.ArgumentParser(
        description="DeepSeek Client - AI-powered text analysis and question answering"
    )
    
    # Global options
    parser.add_argument("--config", type=str, help="Path to config file")
    parser.add_argument("--api-key", type=str, help="DeepSeek API key")
    parser.add_argument("--base-url", type=str, help="API base URL")
    parser.add_argument("--model", type=str, help="Model name")
    parser.add_argument("--log-level", type=str, default="INFO", 
                       choices=["DEBUG", "INFO", "WARNING", "ERROR"],
                       help="Logging level")
    parser.add_argument("--log-file", type=str, help="Log file path")
    parser.add_argument("--env-file", type=str, help="Environment file path")
    
    # Subcommands
    subparsers = parser.add_subparsers(dest="command", help="Available commands", required=True)
    
    # Ask command
    ask_parser = subparsers.add_parser("ask", help="Ask DeepSeek a question")
    ask_parser.add_argument("question", type=str, help="Question to ask")
    ask_parser.add_argument("--system-prompt", type=str, help="System prompt")
    ask_parser.add_argument("--chinese", action="store_true", 
                           help="Use Chinese technical response mode")
    ask_parser.add_argument("--domain", type=str, default="技术", 
                           help="Technical domain for Chinese mode")
    ask_parser.add_argument("--context-file", type=str, 
                           help="JSON file containing context information")
    ask_parser.add_argument("--output", type=str, help="Output file path")
    
    # Batch ask command
    batch_parser = subparsers.add_parser("batch", help="Ask multiple questions")
    batch_parser.add_argument("questions_file", type=str, 
                             help="File containing questions (one per line or JSON)")
    batch_parser.add_argument("--output-dir", type=str, 
                             help="Output directory for answers")
    batch_parser.add_argument("--system-prompt", type=str, help="System prompt")
    batch_parser.add_argument("--chinese", action="store_true", 
                             help="Use Chinese technical response mode")
    
    # Test connection command
    test_parser = subparsers.add_parser("test", help="Test API connection")
    
    return parser


def main():
    """Main CLI entry point"""
    # Check if first argument is a known subcommand to decide parsing strategy
    known_commands = ['ask', 'batch', 'test']
    use_subcommands = len(sys.argv) > 1 and sys.argv[1] in known_commands
    
    if use_subcommands:
        # Use the old subcommand-based parser
        parser = create_subcommand_parser()
        args = parser.parse_args()
    else:
        # Use simple interface parser (like ds-client)  
        parser = create_simple_parser()
        args = parser.parse_args()
    
    # Setup logging
    logger = setup_logging(args.log_level, args.log_file)
    
    # Load environment file if specified
    if args.env_file:
        load_env_file(args.env_file)
    else:
        load_env_file()  # Try to load from default locations
    
    try:
        # Create config
        config = create_config_from_args(args)
        
        # Create client
        client = DeepSeekClient(config, logger)
        
        # Execute command
        if hasattr(args, 'command') and args.command:
            # Subcommand mode
            if args.command == "ask":
                handle_ask_command(client, args, logger)
            elif args.command == "batch":
                handle_batch_command(client, args, logger)
            elif args.command == "test":
                handle_test_command(client, logger)
        elif hasattr(args, 'list') and args.list:
            # History list command
            handle_history_list_command(logger)
        elif hasattr(args, 'show') and args.show:
            # History show command
            handle_history_show_command(args.show, logger)
        elif hasattr(args, 'prompt') and (args.prompt or args.file):
            # Simple interface mode (like ds-client)
            handle_simple_command(client, args, logger)
        else:
            # Show help based on which parser we used
            known_commands = ['ask', 'batch', 'test']
            if len(sys.argv) > 1 and sys.argv[1] in known_commands:
                create_subcommand_parser().print_help()
            else:
                create_simple_parser().print_help()
            sys.exit(1)
            
    except Exception as e:
        logger.error(f"Error: {e}")
        sys.exit(1)


def create_config_from_args(args) -> DeepSeekConfig:
    """Create DeepSeekConfig from command line arguments"""
    # Start with auto-config which handles .env loading
    try:
        config = DeepSeekConfig.auto_config()
    except ValueError as e:
        # If auto-config fails and no CLI args provided, raise error
        if not (hasattr(args, 'api_key') and args.api_key):
            raise ValueError(f"Configuration failed: {e}. Please set DEEPSEEK_API_KEY or use --api-key")
        # Create minimal config if CLI args provided
        config = DeepSeekConfig(api_key="", skip_validation=True)
    
    # Override with command line arguments
    if hasattr(args, 'api_key') and args.api_key:
        config.api_key = args.api_key
        config.skip_validation = False  # If API key provided via CLI, enable validation
    if hasattr(args, 'base_url') and args.base_url:
        config.base_url = args.base_url
    if hasattr(args, 'model') and args.model:
        config.model_name = args.model
    
    # Only validate API key if validation is not skipped
    if not config.skip_validation and not validate_api_key(config.api_key):
        raise ValueError("Valid API key is required. Set DEEPSEEK_API_KEY, use --api-key, or set QWEN_SKIP_API_VALIDATION=true")
    
    return config


def handle_ask_command(client: DeepSeekClient, args, logger):
    """Handle ask command"""
    # Load context if provided
    context = {}
    if args.context_file:
        context_path = Path(args.context_file)
        if context_path.exists():
            with open(context_path, 'r', encoding='utf-8') as f:
                context = json.load(f)
            logger.info(f"Loaded context from: {context_path}")
    
    # Ask question
    if args.chinese:
        response = client.ask_chinese_technical(
            args.question, context, args.domain
        )
    elif context:
        response = client.ask_with_context(
            args.question, context, args.system_prompt
        )
    else:
        response = client.ask(args.question, args.system_prompt)
    
    # Output response
    if args.output:
        output_path = Path(args.output)
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(response)
        logger.info(f"Response saved to: {output_path}")
    else:
        print(response)


def handle_batch_command(client: DeepSeekClient, args, logger):
    """Handle batch command"""
    # Load questions
    questions_path = Path(args.questions_file)
    if not questions_path.exists():
        raise FileNotFoundError(f"Questions file not found: {questions_path}")
    
    questions = []
    with open(questions_path, 'r', encoding='utf-8') as f:
        content = f.read().strip()
        
        # Try to parse as JSON first
        try:
            data = json.loads(content)
            if isinstance(data, list):
                questions = data
            elif isinstance(data, dict) and 'questions' in data:
                questions = data['questions']
            else:
                raise ValueError("Invalid JSON format")
        except json.JSONDecodeError:
            # Parse as line-separated questions
            questions = [line.strip() for line in content.split('\n') if line.strip()]
    
    logger.info(f"Loaded {len(questions)} questions")
    
    # Process questions
    results = client.batch_ask(questions, args.system_prompt)
    
    # Save results
    if args.output_dir:
        output_dir = Path(args.output_dir)
        output_dir.mkdir(parents=True, exist_ok=True)
        
        for i, (question, answer) in enumerate(results.items(), 1):
            filename = f"answer_{i:03d}.md"
            answer_file = output_dir / filename
            
            with open(answer_file, 'w', encoding='utf-8') as f:
                f.write(f"# Question {i}\n\n")
                f.write(f"**Question**: {question}\n\n")
                f.write(f"**Answer**:\n\n{answer}\n")
            
            logger.info(f"Answer {i} saved to: {answer_file}")
        
        # Also save summary
        summary_file = output_dir / "summary.json"
        with open(summary_file, 'w', encoding='utf-8') as f:
            json.dump(results, f, indent=2, ensure_ascii=False)
        logger.info(f"Summary saved to: {summary_file}")
    else:
        # Print results
        for i, (question, answer) in enumerate(results.items(), 1):
            print(f"\n=== QUESTION {i} ===")
            print(question)
            print(f"\n=== ANSWER {i} ===")
            print(answer)
            print("\n" + "="*50)


def handle_test_command(client: DeepSeekClient, logger):
    """Handle test command"""
    logger.info("Testing connection to DeepSeek API...")
    
    try:
        if client.validate_connection():
            logger.info("✅ Connection test successful")
            print("Connection to DeepSeek API is working correctly")
        else:
            logger.error("❌ Connection test failed")
            print("Failed to connect to DeepSeek API")
            sys.exit(1)
    except Exception as e:
        logger.error(f"❌ Connection test error: {e}")
        print(f"Connection test failed with error: {e}")
        sys.exit(1)


def handle_simple_command(client: DeepSeekClient, args, logger):
    """Handle simple interface commands (like ds-client)"""
    # Regular prompt/response handling
    prompt = ""
    output_file = None
    
    if args.file:
        # Read prompt from file
        file_path = Path(args.file)
        if not file_path.exists():
            logger.error(f"File not found: {file_path}")
            sys.exit(1)
        
        with open(file_path, 'r', encoding='utf-8') as f:
            prompt = f.read().strip()
        
        logger.info(f"Loaded prompt from: {file_path}")
        
        # Determine output file for markdown files
        if file_path.suffix.lower() in ['.md', '.markdown']:
            # Create output filename like input_answer.md
            stem = file_path.stem
            output_file = file_path.parent / f"{stem}_answer{file_path.suffix}"
    
    elif args.prompt:
        # Use direct prompt
        prompt = args.prompt
    
    else:
        logger.error("Either prompt text or --file must be provided")
        sys.exit(1)
    
    if not prompt:
        logger.error("No prompt text found")
        sys.exit(1)
    
    # Ask the question
    logger.info("Sending prompt to DeepSeek...")
    try:
        response = client.ask(prompt, args.system_prompt)
        
        if output_file:
            # Save to output file
            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(response)
            logger.info(f"Response saved to: {output_file}")
        else:
            # Print to screen
            print(response)
            
    except Exception as e:
        logger.error(f"Error getting response: {e}")
        sys.exit(1)


def handle_history_list_command(logger):
    """Handle --list command to show Q&A history"""
    try:
        history_manager = QAHistoryManager()
        entries = history_manager.get_entries(limit=50)  # Show last 50 entries
        
        if not entries:
            print("No Q&A history found.")
            return
        
        print(f"Found {len(entries)} Q&A entries:\n")
        print(f"{'ID':<5} {'Model':<10} {'Date':<20} {'Question':<60}")
        print("-" * 95)
        
        for entry in entries:
            date_str = entry.timestamp.strftime("%Y-%m-%d %H:%M:%S") if entry.timestamp else "Unknown"
            chinese_indicator = " (中文)" if entry.chinese_mode else ""
            domain_info = f" [{entry.domain}]" if entry.domain else ""
            
            print(f"{entry.id:<5} {entry.model:<10} {date_str:<20} {entry.question_preview:<60}")
            if chinese_indicator or domain_info:
                print(f"{'':26}{chinese_indicator}{domain_info}")
        
        # Show statistics
        stats = history_manager.get_statistics()
        print(f"\n📊 Statistics:")
        print(f"   Total entries: {stats['total_entries']}")
        print(f"   Qwen entries: {stats['qwen_entries']}")
        print(f"   DeepSeek entries: {stats['deepseek_entries']}")
        print(f"   OSS entries: {stats['oss_entries']}")
        print(f"   Chinese entries: {stats['chinese_entries']}")
        print(f"   Recent (7 days): {stats['recent_entries']}")
        if stats['avg_response_time']:
            print(f"   Avg response time: {stats['avg_response_time']:.2f}s")
        
    except Exception as e:
        logger.error(f"Error listing history: {e}")
        sys.exit(1)


def handle_history_show_command(question_id: int, logger):
    """Handle --show command to display specific Q&A entry"""
    try:
        history_manager = QAHistoryManager()
        entry = history_manager.get_entry(question_id)
        
        if not entry:
            print(f"No Q&A entry found with ID {question_id}")
            sys.exit(1)
        
        # Display the entry
        print(f"📋 Q&A Entry #{entry.id}")
        print("=" * 80)
        
        # Metadata
        date_str = entry.timestamp.strftime("%Y-%m-%d %H:%M:%S") if entry.timestamp else "Unknown"
        print(f"🕒 Date: {date_str}")
        print(f"🤖 Model: {entry.model}")
        if entry.chinese_mode:
            print(f"🇨🇳 Chinese Mode: Yes (Domain: {entry.domain or 'N/A'})")
        if entry.system_prompt:
            print(f"⚙️  System Prompt: {entry.system_prompt[:100]}{'...' if len(entry.system_prompt) > 100 else ''}")
        if entry.response_time:
            print(f"⏱️  Response Time: {entry.response_time:.2f}s")
        if entry.tokens_used:
            print(f"🔢 Tokens Used: {entry.tokens_used}")
        
        print("\n" + "=" * 80)
        
        # Question
        print("❓ QUESTION:")
        print("-" * 40)
        print(entry.question)
        print()
        
        # Answer
        print("💬 ANSWER:")
        print("-" * 40)
        print(entry.answer)
        
        # Context if available
        if entry.context:
            print("\n📖 CONTEXT:")
            print("-" * 40)
            for title, content in entry.context.items():
                print(f"• {title}: {content[:200]}{'...' if len(content) > 200 else ''}")
        
    except Exception as e:
        logger.error(f"Error showing entry: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
